package com.ruoyi.system.service.impl;

import cn.hutool.json.JSONUtil;
import com.ruoyi.common.core.domain.MemberCarConstants;
import com.ruoyi.common.core.domain.entity.*;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ParkingApiUtil;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.system.mapper.InfoLogMapper;
import com.ruoyi.system.mapper.MemberCarMapper;
import com.ruoyi.system.mapper.ParkConfigMapper;
import com.ruoyi.system.service.IMemberCarService;
import com.ruoyi.system.third.constant.SysConstant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class MemberCarServiceImpl implements IMemberCarService {

    private static final Logger log = LoggerFactory.getLogger(HttpUtils.class);


    @Autowired
    private MemberCarMapper memberCarMapper;

    @Autowired
    private ParkConfigMapper parkConfigMapper;

    @Autowired
    private ParkingApiUtil parkingApiUtil;

    @Autowired
    private InfoLogMapper infoLogMapper;

    /**
     * 获取会员车辆详细信息
     */
    @Override
    public Integer queryByCarNum(String carNum) {
        return memberCarMapper.queryByCarNum(carNum);
    }


    /**
     * 查询某个会员绑定的车辆
     */
    @Override
    public List<MemberCar> listByMemberCar(String memberPhone) {
        return memberCarMapper.listByMemberCar(memberPhone);
    }


    /**
     * 分页查询会员车辆列表
     */
    @Override
    public List<MemberCar> selectMemberCarList(MemberCarPageQuery query) {
        return memberCarMapper.selectMemberCarList(query);
    }

    /**
     * 获取会员车辆详细信息
     */
    @Override
    public MemberCar selectMemberCarById(Long id) {
        return memberCarMapper.selectMemberCarById(id);
    }

    /**
     * 新增会员车辆
     *
     */

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> insertMemberCar(MemberCar memberCar, Integer carStatus) {
        Map<String, Object> result = new HashMap<>();
        boolean success = false;
        String message = "";

        String carNumber = memberCar.getCarNum();
        // 自动填充创建人、创建时间、绑定时间（可通过拦截器或手动设置）
        memberCar.setCreateBy(memberCar.getMemberPhone());
        memberCar.setCreateTime(DateUtils.getNowDate());
        memberCar.setBindTime(DateUtils.getNowDate());

        //判断这辆车是否在临时库中，如果在临时库中，进场的时候已经享受过一次减免，从临时车辆库中删除

        if(carStatus == MemberCarConstants.CAR_STATUS_N){
            memberCarMapper.deleteTempByCarNum(carNumber);
        }

        //  根据车牌号查询：车辆已经进场 、未出场，且未享受优惠的
        int exist = memberCarMapper.queryCarLog(carNumber);

        if(exist > 0){

            // 车辆已进场且未享受优惠，推送优惠
            String parkCode = SysConstant.PROJECT_CODE;
            ParkConfig config = new ParkConfig();
            config.setParkId(parkCode);
            RuleConfig ruleConfig = parkConfigMapper.selectRuleConfigByParkCode(config);
            Integer freeTime = ruleConfig.getMemberFreeMinutes();

            log.info("{} 会员绑定车牌 {}，车辆在场内，准备推送减免优惠，减免时间：{}分钟",memberCar.getMemberPhone(), carNumber, freeTime);

            Map<String, Object> map = parkingApiUtil.addMemberRelief(carNumber, parkCode, freeTime);

            // 判断推送结果
            if (map != null && MemberCarConstants.SUCCESS_CODE_STRING.equals(map.get("resCode").toString())) {
                log.info("会员绑定车牌，推送减免结果：成功，车牌号：{}，减免时间：{}分钟", carNumber, freeTime);
                message = "车辆已进场并享受了会员优惠";
//               更新为已享受减免
              memberCarMapper.updateCarLog(carNumber,"车辆管理中绑定车辆时打折");


                // 保存车辆绑定时的打折日志信息
                InfoLog infoLog = new InfoLog();
                infoLog.setVehiclePlate(carNumber);

//操作类型：1=进场打折，2=出场，3=通知车场已支付 ，4=车辆已进场且未享受优惠在添加车辆时打折，
// 5=进场，6=查询缴费时添加车辆但推送打折失败，7=添加车辆但推送打折失败，8=车辆已进场且未享受优惠在查询交费时添加车辆并打折
                infoLog.setActionType(4);
                infoLog.setActionTime(new Date());
                // 转换为 JSON 字符串
                infoLog.setJsonData(JSONUtil.toJsonStr( map.get("jsonResult")));
                infoLogMapper.insertInfoLog(infoLog);

            } else {
                log.warn("会员绑定车牌，推送减免结果：失败，车牌号：{}，原因：{}", carNumber, map.getOrDefault("resMsg", "未知错误"));
//                message = "车辆已进场";
                message = JSONUtil.toJsonStr(map.getOrDefault("resMsg", "未知错误")) ;

                // 保存车辆绑定时的打折日志信息
                InfoLog infoLog = new InfoLog();
                infoLog.setVehiclePlate(carNumber);

//操作类型：1=进场打折，2=出场，3=通知车场已支付 ，4=车辆已进场且未享受优惠在添加车辆时打折，
// 5=进场，6=查询缴费时添加车辆但推送打折失败，7=添加车辆但推送打折失败，8=车辆已进场且未享受优惠在查询交费时添加车辆并打折
                infoLog.setActionType(7);
                infoLog.setActionTime(new Date());
                // 转换为 JSON 字符串
                infoLog.setJsonData(JSONUtil.toJsonStr( map.get("jsonResult")));
                String errorMsg = "会员绑定车牌，推送减免结果：失败"+"车牌号"+carNumber+map.getOrDefault("resMsg", "未知错误");
                infoLog.setErrorMessage(errorMsg);
                infoLogMapper.insertInfoLog(infoLog);

            }
        } else {
            // 车辆未进场
            log.info("会员绑定车牌 {}，车辆不在场内，无需推送减免优惠", carNumber);
            message = "车辆未进场或已享受优惠，绑定成功！";
        }

//        如果是已解绑的，更新
        if(carStatus == MemberCarConstants.CAR_STATUS_UNBOUND){
            int updateResult = memberCarMapper.updateMemberCar(memberCar);
            success = updateResult > 0;

        }else{
            // 执行数据库插入操作
            int insertResult = memberCarMapper.insertMemberCar(memberCar);
            success = insertResult > 0;
        }

        log.info("{} 会员绑定车牌 成功{}",memberCar.getMemberPhone(), carNumber);

        // 构建返回结果
        result.put("success", success);
        result.put("message", message);
        result.put("carNum", carNumber);

        return result;
    }

    /**
     * 修改会员车辆
     */
    @Override
    public int updateMemberCar(MemberCar memberCar) {
        // 自动填充更新人、更新时间
        memberCar.setUpdateBy(getUsername());
        memberCar.setUpdateTime(DateUtils.getNowDate());
        return memberCarMapper.updateMemberCar(memberCar);
    }

    /**
     * 删除会员车辆
     */
    @Override
    public int deleteMemberCarById(Long id) {
        return memberCarMapper.deleteMemberCarById(id);
    }

    /**
     * 批量删除会员车辆
     */
    @Override
    public int deleteMemberCarByIds(Long[] ids) {
        return memberCarMapper.deleteMemberCarByIds(ids);
    }

    /**
     * 根据车牌号查询会员车辆状态、绑定人 等信息
     *
     */
    @Override
    public MemberCar judgeMemberCarInfo(MemberCar memberCar) {
        return memberCarMapper.selectMemberCarByCarNumInfo(memberCar.getCarNum());

    }

    /**
     * 未找到记录返回零
     *
     */
    @Override
    public int judgeMemberCar(MemberCar memberCar) {
        try {
            Integer carStatus = memberCarMapper.selectMemberCarByCarNum(memberCar.getCarNum());
            return carStatus != null ? carStatus : 0;
        } catch (Exception e) {
            // 抛出业务异常，携带错误码
            throw new ServiceException("车牌状态查询失败，请联系管理员", 5000);
        }
    }




    // 获取当前用户（示例方法，需根据实际权限框架调整）
    private String getUsername() {
        // 结合 Spring Security 获取当前登录用户
        // return SecurityContextHolder.getContext().getAuthentication().getName();
        return "system"; // 临时默认值
    }

    /**
     * 查询会员车辆信息
     */
    @Override
    public MemberCar findByCarNum(String carNum) {
        return memberCarMapper.findByCarNum(carNum);
    }



    /**
     * 新增会员车辆，查询并交费时调用，查询并交费时绑定会员车辆
     *
     */

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> insertMemberCarOfJudgeParkIn(MemberCar memberCar, Integer carStatus) {
        Map<String, Object> result = new HashMap<>();
        boolean success = false;
        String message = "";

        String carNumber = memberCar.getCarNum();
        // 自动填充创建人、创建时间、绑定时间（可通过拦截器或手动设置）
        memberCar.setCreateBy(memberCar.getMemberPhone());
        memberCar.setCreateTime(DateUtils.getNowDate());
        memberCar.setBindTime(DateUtils.getNowDate());

        //判断这辆车是否在临时库中，如果在临时库中，进场的时候已经享受过一次减免，从临时车辆库中删除

        if(carStatus == MemberCarConstants.CAR_STATUS_N){
            memberCarMapper.deleteTempByCarNum(carNumber);
        }

        //  根据车牌号查询：车辆已经进场 、未出场，且未享受优惠的
        int exist = memberCarMapper.queryCarLog(carNumber);

        if(exist > 0){

            // 车辆已进场且未享受优惠，推送优惠
            String parkCode = SysConstant.PROJECT_CODE;
            ParkConfig config = new ParkConfig();
            config.setParkId(parkCode);
            RuleConfig ruleConfig = parkConfigMapper.selectRuleConfigByParkCode(config);
//            RuleConfig ruleConfig = new RuleConfig();
//                    ruleConfig.setMemberFreeMinutes(120);
            Integer freeTime = ruleConfig.getMemberFreeMinutes();

            log.info("{} 会员点击查询交费前先绑定车牌 {}，车辆在场内，准备推送减免优惠，减免时间：{}分钟",memberCar.getMemberPhone(), carNumber, freeTime);

            Map<String, Object> map = parkingApiUtil.addMemberRelief(carNumber, parkCode, freeTime);

            // 判断推送结果
            if (map != null && MemberCarConstants.SUCCESS_CODE_STRING.equals(map.get("resCode").toString())) {
                log.info("会员先绑定车牌，推送减免结果：成功，车牌号：{}，减免时间：{}分钟", carNumber, freeTime);
                message = "车辆已进场并享受了会员优惠";
//               更新为已享受减免
                memberCarMapper.updateCarLog(carNumber,"查询交费时绑定车辆并打折");

                // 保存车辆在查询交费操作前，绑定车辆并打折的日志信息
                InfoLog infoLog = new InfoLog();
                infoLog.setVehiclePlate(carNumber);

//操作类型：1=进场打折，2=出场，3=通知车场已支付 ，4=车辆已进场且未享受优惠在添加车辆时打折，
// 5=进场，6=查询缴费时添加车辆但推送打折失败，7=添加车辆但推送打折失败，8=车辆已进场且未享受优惠在查询交费时添加车辆并打折
                infoLog.setActionType(8);
                infoLog.setActionTime(new Date());
                // 转换为 JSON 字符串
                infoLog.setJsonData(JSONUtil.toJsonStr( map.get("jsonResult")));
                infoLogMapper.insertInfoLog(infoLog);

            } else {
                log.warn("会员绑定车牌，推送减免结果：失败，车牌号：{}，原因：{}", carNumber, map.getOrDefault("resMsg", "未知错误"));
                message = JSONUtil.toJsonStr(map.getOrDefault("resMsg", "未知错误")) ;

                // 保存车辆绑定时的打折日志信息
                InfoLog infoLog = new InfoLog();
                infoLog.setVehiclePlate(carNumber);

//操作类型：1=进场打折，2=出场，3=通知车场已支付 ，4=车辆已进场且未享受优惠在添加车辆时打折，
// 5=进场，6=查询缴费时添加车辆但推送打折失败，7=添加车辆但推送打折失败，8=车辆已进场且未享受优惠在查询交费时添加车辆并打折
                infoLog.setActionType(6);
                infoLog.setActionTime(new Date());
                // 转换为 JSON 字符串
                infoLog.setJsonData(JSONUtil.toJsonStr( map.get("jsonResult")));
                String errorMsg = "会员绑定车牌，推送减免结果：失败"+"车牌号"+carNumber+map.getOrDefault("resMsg", "未知错误");
                infoLog.setErrorMessage(errorMsg);
                infoLogMapper.insertInfoLog(infoLog);

            }
        } else {
            // 车辆未进场
            log.info("会员绑定车牌 {}，车辆不在场内，无需推送减免优惠", carNumber);
            message = "车辆未进场无法享受优惠，绑定成功！";
        }

//        如果是已解绑的，更新,状态改成绑定中
        if(carStatus == MemberCarConstants.CAR_STATUS_UNBOUND){
            memberCar.setCarStatus(1);
            int updateResult = memberCarMapper.updateMemberCar(memberCar);
            success = updateResult > 0;

        }else{
            // 执行数据库插入操作
            memberCar.setCarStatus(1);
            int insertResult = memberCarMapper.insertMemberCar(memberCar);
            success = insertResult > 0;
        }

        log.info("{} 会员绑定车牌 成功{}",memberCar.getMemberPhone(), carNumber);

        // 构建返回结果
        result.put("success", success);
        result.put("message", message);
        result.put("carNum", carNumber);

        return result;
    }


}
